package com.ordertracker;


import com.ordertracker.core.PersistentEventRegister;
import com.ordertracker.service.InitialService;
import com.sun.jersey.api.json.JSONMarshaller;
import com.sun.jersey.api.json.JSONUnmarshaller;
import org.apache.log4j.Logger;

import javax.ws.rs.core.SecurityContext;
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;


/**
 * Description of class. Created 11/23/12 5:39 PM
 * 
 * @author andrey.rodin@playtech.com
 */
 
public final class Application {

    private static Logger logger = Logger.getLogger(Application.class);
    private String name;
    private String fullName;
    private String version;
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private static Properties properties;
    private static ConcurrentHashMap<String, String> property = new ConcurrentHashMap<String, String>();
    private static final Application INSTANCE = new Application();
    private APP_STATUS status;
    private ApplicationConfig config;
    private JSONMarshaller jsonMarshaller;
    private JSONUnmarshaller jsonUnmarshaller;
    private Map<String, Session> sessionCash;

    private Application() {
        status = APP_STATUS.STARTING;
        sessionCash =  new ConcurrentHashMap<String, Session>();
        logger.info("==========!!!!!!!!!!====="+status);
    }

    public void init(ApplicationConfig config) {
        status = APP_STATUS.INITIALIZING;
        logger.info("==========!!!!!!!!!!====="+status);
        properties = new Properties();
        loadProperty("app.properties");
        name = properties.getProperty("name");
        fullName = properties.getProperty("full_name");
        version = properties.getProperty("version");
        config.setHostname(properties.getProperty("hostname"));
        config.setAuthorizationType(getPropertyAuthorizationType("type_auth"));
        config.setTimezone(TimeZone.getTimeZone(properties.getProperty("time_zone")));
        this.config = config;
        status = APP_STATUS.RUNNING;
        logger.info("==========!!!!!!!!!!====="+status);
        logger.info("==========!!!!!!!!!!=====CONTEXT"+config.getContext());
        InitialService initialService= (InitialService) config.getContext().getBean("initialService");
        initialService.registerConstraints((PersistentEventRegister) config.getContext().getBean("persistentEventRegister"));
        initialService.checkUsers();

    }

    private String getPropertyAuthorizationType(String type_auth) {
        if ("BASIC".equals(type_auth)) {
            return SecurityContext.BASIC_AUTH;
        } else if ("CLIENT_CERT".equals(type_auth)) {
            return SecurityContext.CLIENT_CERT_AUTH;
        } else if ("DIGEST".equals(type_auth)) {
            return SecurityContext.DIGEST_AUTH;
        } else if ("FORM".equals(type_auth)) {
            return SecurityContext.FORM_AUTH;
        }
        return null;
    }

    public void destroy(ApplicationConfig config) {
        logger.info("==========!!!!!!!!!==== DESTROY");

    }


    private static enum APP_STATUS {
        STOP,
        STARTING,
        INITIALIZING,
        RUNNING,
    }

    public static final Application getApplication() {
        return INSTANCE;
    }

    public String getName() {
        return name;
    }

    public APP_STATUS getStatus() {
        return status;
    }

    public ApplicationConfig getConfig() {
        return config;
    }

    public Map<String, Session> getSessionCash() {
        return sessionCash;
    }

    public JSONMarshaller getJsonMarshaller() {
        return jsonMarshaller;
    }

    public void setJsonMarshaller(JSONMarshaller jsonMarshaller) {
        this.jsonMarshaller = jsonMarshaller;
    }

    public JSONUnmarshaller getJsonUnmarshaller() {
        return jsonUnmarshaller;
    }

    public void setJsonUnmarshaller(JSONUnmarshaller jsonUnmarshaller) {
        this.jsonUnmarshaller = jsonUnmarshaller;
    }

    private void loadProperty(String filePath) {
        lock.writeLock().lock();
        try {
            properties.load(Application.class.getResourceAsStream("/"+filePath));
        } catch (Exception ex) {
            System.out.println("Can not load properties due to: " + ex);
        } finally {
            lock.writeLock().unlock();
        }

    }
}
